大家好,昨天完成了資料的標準化,今天就要進行模型的建立,在這個問題一開始就有講到,會以one-hot coding和數值兩種表示方法的屬性資料來訓練模型,之後比較兩者的不同,接下來會先建立以數值表示屬性資料來訓練的模型。
首先準備兩種模型都一樣資料,寶可夢對應的索引以及預期答案資料:
x_train_index = np.array(train_data.drop('Winner', axis='columns'))
x_val_index = np.array(val_data.drop('Winner', axis='columns'))
x_test_index = np.array(test_data.drop('Winner', axis='columns'))
y_train = np.array(train_data['Winner'])
y_val = np.array(val_data['Winner'])
y_test = np.array(test_data['Winner'])
再來是將屬性資料以數值表示,要先取得寶可夢能力值資料,再透過索引產生輸入資料:
pokemon_data_normal = np.array(pokemon_df.loc[:, :'Legendary'])
x_train_normal = pokemon_data_normal[x_train_index -1].reshape((-1, 20))
x_val_normal = pokemon_data_normal[x_val_index -1].reshape((-1, 20))
x_test_normal = pokemon_data_normal[x_test_index -1].reshape((-1, 20))
print(x_train_normal.shape)
接下來就要開始建立和訓練模型,模型的架構跟上一個題目有一些不同,在房價預測模型裡只使用到全連接層,而在這個模型裡除了全連接層外,還會在每層的輸出加上dropout層,dropout層會根據設定的捨棄率,隨機捨棄模型中的參數,可以讓模型在訓練時使用不同的神經元,避免過度依賴局部特徵。
這個模型架構有四層全連接層,激活函數使用ReLU,然後有四層dropout層分別接在全連接層之後,dropout層的捨棄率設定成30%。模型的輸入為兩隻寶可夢資料,一隻寶可夢有10種不同的資料,因此輸入資料維度為20。輸出層的輸出資料維度是1,激活函數使用Sigmoid:
inputs = keras.Input(shape=(20, ))
x = layers.Dense(64, activation='relu')(inputs)
x = layers.Dropout(0.3)(x)
x = layers.Dense(128, activation='relu')(x)
x = layers.Dropout(0.3)(x)
x = layers.Dense(64, activation='relu')(x)
x = layers.Dropout(0.3)(x)
x = layers.Dense(32, activation='relu')(x)
x = layers.Dropout(0.3)(x)
outputs = layers.Dense(1, activation='sigmoid')(x)
model_1 = keras.Model(inputs, outputs, name='model-1')
再來要設定優化器、損失函數、指數函數,優化器使用Adam;損失函數使用binary cross entropy;指數函數使用
binary accuracy:
model_1.compile(keras.optimizers.Adam(),
loss=keras.losses.BinaryCrossentropy(),
metrics=[keras.metrics.BinaryAccuracy()])
然後建立模型儲存位置跟設定回調函數:
model_dir = 'lab3-logs/models'
os.makedirs(model_dir)
log_dir = os.path.join('lab3-logs', 'model-1')
model_cbk = keras.callbacks.TensorBoard(log_dir=log_dir)
model_mckp=keras.callbacks.ModelCheckpoint(model_dir+'/Best-model-1.h5',
monitor='val_binary_accuracy',
save_best_only=True,
mode='max')
最後就是訓練模型,這部分的參數設定就跟上一個模型一樣,批次傳入資料大小為64,訓練300次:
history_1 = model_1.fit(x_train_normal, y_train,
batch_size=64 ,
epochs=300,
validation_data=(x_val_normal, y_val),
callbacks=[model_cbk, model_mckp])